﻿using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace FastDFS.Client
{
    public abstract class FdfsServer
    {
        protected TcpClient TcpClient { get; private set; }

        protected string Ip { get; private set; }

        protected int Port { get; private set; }

        protected FdfsServer(string ip, int port)
        {
            this.Ip = ip;
            this.Port = port;
        }

        public void ChangeIp(string ip)
        {
            this.Ip = ip;
        }

        public void ChangePort(int port)
        {
            this.Port = port;
        }

        protected FdfsServer(IPEndPoint ipEndPoint) : this(ipEndPoint.Address.ToString(), ipEndPoint.Port)
        {
        }

        /// <summary>
        /// get the connected TcpClient
        /// </summary>
        /// <returns>the TcpClient</returns>
        public virtual async Task<TcpClient> GetSocketAsync()
        {
            if (this.TcpClient == null)
            {
                this.TcpClient = await ClientGlobal.GetSocketAsync(this.Ip, this.Port);
            }
            else if (!this.TcpClient.Connected)
            {
                try
                {
#if NETSTANDARD2_0 || NET461
                    this.TcpClient.Dispose();
#endif
#if NET45
                    this.TcpClient.Close();
#endif
                }
                catch
                {
                    // ignore
                }

                this.TcpClient = await ClientGlobal.GetSocketAsync(this.Ip, this.Port);
            }
            return this.TcpClient;
        }

        public async Task<bool> TryConntectAsync()
        {
            await this.GetSocketAsync();
            return true;
        }

        public Stream GetOutputStream()
        {
            return this.TcpClient.GetStream();
        }

        public Stream GetInputStream()
        {
            return this.TcpClient.GetStream();
        }

        public virtual void Close()
        {
            if (ClientGlobal.Close(this.TcpClient))
            {
                this.TcpClient = null;
            }
        }
    }
}
